#include <iostream>
#include <unordered_set>

#include "depends/runtime_stub.h"
#include "base/nlohmann/json.hpp"

class MockRuntimeStub : public bts::RuntimeStub {
 public:
  bts::Status rtMalloc(void **ptr, size_t size) {
    (void)ptr;
    (void)size;
    std::cout << "Call rtMalloc Failed!" << std::endl;
    return bts::Status::FAILED;
  }

  bts::Status rtFree(void *ptr) {
    return bts::Status::SUCCESS;
  }
};

bts::Status rtMallocFunc(void **ptr, size_t size) {
  return bts::RuntimeStub().GetInstance()->rtMalloc(ptr, size);
}

int ParseVersionValue(const std::string &str)
{
  if (str.empty()) {
    return 0;
  }
  int major = 0;
  int minor = 0;
  size_t end = str.find('+');
  size_t pos = str.find('.');
  try {
    major = std::stoi(str.substr(0, pos));
    minor = std::stoi(str.substr(pos + 1, end));
  } catch (...) {
    std::cout << " can not be converted to version value" << std::endl;
  }
  return 1000 * major + 10 * minor;
}

void TestJson() {
  nlohmann::json js = R"({
    "BF16": {
        "runtime" : "7.1",
      "driver": "7.1+",
      "socLists" : ["910B", "910C"]
    }
  })"_json;
  int runtime;
  int driver;
  std::unordered_set<std::string> soc_versions;
  try {
    runtime = ParseVersionValue(js.at("BF16").at("runtime"));
    driver = ParseVersionValue(js.at("BF16").at("driver"));
    soc_versions = js.at("BF16").at("socLists").get<std::unordered_set<std::string>>();
  } catch (const nlohmann::json::exception &e) {
    std::cout << e.what() << std::endl;
  }
  std::cout << "runtime=" << runtime << std::endl;
  std::cout << "driver=" << driver << std::endl;
  for (const auto& s : soc_versions) {
    std:: cout << "  soc=" << s << std::endl;
  }
}

int main() {
  std::cout << "Hello, World!" << std::endl;
  auto mock_runtime = std::make_shared<MockRuntimeStub>();
  bts::RuntimeStub::SetInstance(mock_runtime);
  void *ptr = nullptr;
  size_t alloc_size = 8;
  rtMallocFunc(&ptr, alloc_size);
  bts::RuntimeStub::Reset();

  TestJson();
  return 0;
}
